梦入琼楼寒有月,行过石树冻无烟

Spring security 创建项目与自定义登陆页

本文通过idea进行一些实例演示,通过Spring Initializer工具来创建spring security项目的例子,首先我们在自动构建项目中选择 Spring security 以及 Spring Web,然后点击next即可进行下一步,通过Spring Initializer来选定一些常用的项目以来,当创建项目完成后,Idea将会自动生成pom.xml文件,我们可以通过该文件看出Spring Initializr总共引入了那些依赖:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

DomeApplication.class

在程序的启动类中,我们可以通过设置一个程序入口来访问,之后Spring security会在访问的时候直接使用其自带的登入页面,而登入页面的帐号及其密码则通过application.properties即spring全局配置文件中进行配置,启动类代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package com.example.dome;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@SpringBootApplication
public class DomeApplication {
@GetMapping("/")
public String index() {
return "Helo,world,the is Spring security world.";
}
public static void main(String[] args) {
SpringApplication.run(DomeApplication.class, args);
}

}

application.properties

1
2
3
// user@帐号 passowrd@密码
spring.security.user.name=kun
spring.security.user.password=123

自定义登陆页

WebSecurityConfig.class

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package com.example.dome.configuration;

import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
import org.springframework.security.config.annotation.web.configurers.FormLoginConfigurer;

@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure (HttpSecurity httpSecurity) throws Exception {
ExpressionUrlAuthorizationConfigurer.ExpressionInterceptUrlRegistry expressionInterceptUrlRegistry = httpSecurity.authorizeRequests();
ExpressionUrlAuthorizationConfigurer.AuthorizedUrl authorizedUrl = (ExpressionUrlAuthorizationConfigurer.AuthorizedUrl) expressionInterceptUrlRegistry.anyRequest();
authorizedUrl.authenticated();

FormLoginConfigurer<HttpSecurity> formLoginConfigurer =
httpSecurity.formLogin();
formLoginConfigurer.loginPage("/myLogin.html");
formLoginConfigurer.permitAll();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package com.example.dome.configuration;

import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
import org.springframework.security.config.annotation.web.configurers.FormLoginConfigurer;

@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure (HttpSecurity httpSecurity) throws Exception {
httpSecurity.authorizeRequests()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/myLogin.html")
.permitAll()
.and()
.csrf().disable();
}
}

这这里我们主要提供了两种方法,通常我们在写项目的时候都会使用第二种方法,而第一种方法这是一个非常令人无语的事情,使用了HttpSecurity实际上是对应了Spring security命名空间的配置方式,允许我们特定的HTTPP请求配置安全策略,所以相对第二种方法而讲,我们喜欢第二种,HttpSecurity提供了很多配置的相关方法。分别对应命名空间配置中的子标签分如:

ID DA
authorizeRequest() <intercept-url>
formLogin() <form-login>
httpBasic() <http-basic>
csrf() <csrf>

通过调用这些方法后,除了使用and()方法来结束当前标签,才会返回到Httpsecurity,否则将会自动进入对应标签域。authorizeRequests()方法实际撒汗功能返回了一个url拦截注册器,可以调用它提供的anyanyRequest()、antMatchers()和regexMatchers()方法来进行匹配系统的url,并为其指定安全策略。

formLogin()方法和httpBasic()方法都将声明需要Spring security提供表单认证方式,分别返回对应的配置器,其中formLogin().loginPage()为指定自定义登陆页面,同时Spring security会注册一个路由用于接受请求,而csrf()方法则是Spring security所提供的夸站请求伪造 防护公鞥,当WebSeecurityConfig继承WebSecurityConfigurerAdapter的时候将会默认开启csrf()方法。

myLogin.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!-- static/myLogin.html -->
<html>
<head>
<meta charset="UTF-8">
<title>Loing - by Spring security</title>
</head>
<body>
<h1>The is Spring security by html</h1>
<form action="/login" method="post">
<input type="text" name="username" placeholder="user"/>&nbsp;
<input type="password" name="password" placeholder="pass"/>
&nbsp;<input type="submit" value="login go">
</form>
</body>
</html>

指定登陆处理路径

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package com.example.dome.configuration;

import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
import org.springframework.security.config.annotation.web.configurers.FormLoginConfigurer;

@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure (HttpSecurity httpSecurity) throws Exception {
httpSecurity.authorizeRequests()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/myLogin.html")
.loginProcessingUrl("/login") // 指定处理路径
.permitAll()
.and()
.csrf().disable();
}
}

登录成功与登入失败逻辑 (successHandler and failureHandler)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
package com.example.dome.configuration;

import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
import org.springframework.security.config.annotation.web.configurers.FormLoginConfigurer;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure (HttpSecurity httpSecurity) throws Exception {
httpSecurity.authorizeRequests()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/myLogin.html")
.loginProcessingUrl("/login") // 指定处理路径
// 登入成功处理
.successHandler(new AuthenticationSuccessHandler() {
@Override
public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
httpServletResponse.setContentType("application/json;charset=UTF-8");
PrintWriter out = httpServletResponse.getWriter();
out.write("{\"error_code\":\"0\",\"message\":\"Hello login -by spring security\"}");
}
})
// 登入失败处理
.failureHandler(new AuthenticationFailureHandler() {
@Override
public void onAuthenticationFailure(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {
httpServletResponse.setContentType("application/json;charset=UTF-8");
httpServletResponse.setStatus(401);
PrintWriter out = httpServletResponse.getWriter();
// cause
out.write("{\"error_code\":\"401\",\"name\":\"" + e.getClass() + "\", \"message\":\"" + e.getMessage() + "\"}");
}
})
.permitAll()
.and()
.csrf().disable();
}
}
⬅️ Go back